package com.zjst.tree;

/**
 * @author zhanb
 * @date 2020/5/25
 */
public class BinaryTreeDemo {

    public static void main(String[] args) {
        BinaryTree tree = new BinaryTree();
        TreeNode node1  =new TreeNode(1,"宋江");
        TreeNode node2  =new TreeNode(2,"吴用");
        TreeNode node3  =new TreeNode(3,"卢俊义");
        TreeNode node4  =new TreeNode(4,"林冲");
        TreeNode node5  =new TreeNode(5,"关胜");
        TreeNode node6  =new TreeNode(6,"大朗");
        node1.setLeft(node2);
        node2.setRight(node6);
        node1.setRight(node3);
        node3.setLeft(node5);
        node3.setRight(node4);
        tree.setRoot(node1);

        TreeNode node = tree.preSearch(5);
        System.out.println(node);
        //前序遍历  1 2 6 3 5 4
        //tree.preOrder()
        //中序遍历 2 6 1 5 3 4
        //tree.inOrder()
        //后序遍历 6 2 5 4 3 1
        //tree.postOrder()
    }

}

/**
 * 二叉树
 */
class BinaryTree{
    private TreeNode root;

    public void setRoot(TreeNode root) {
        this.root = root;
    }

    /**
     * 前序遍历
     */
    public void preOrder(){
        if (this.root!=null){
            this.root.preOrderTraversal();
        }else{
            System.out.println("二叉树为空");
        }
    }

    /**
     * 中序遍历
     */
    public void inOrder(){
        if (this.root!=null){
            this.root.inOrderTraversal();
        }else{
            System.out.println("二叉树为空");
        }
    }

    /**
     * 后序遍历
     */
    public void postOrder(){
        if (this.root!=null){
            this.root.postOrderTraversal();
        }else{
            System.out.println("二叉树为空");
        }
    }

    /**
     * 前序查找
     * @param no
     * @return
     */
    public TreeNode preSearch(int no){
        if (this.root!=null){
            return this.root.preOrderSearch(no);
        }else {
            return null;
        }
    }

    /**
     * 中序查找
     * @param no
     * @return
     */
    public TreeNode inSearch(int no){
        if (this.root!=null){
            return this.root.inOrderSearch(no);
        }else {
            return null;
        }
    }

    /**
     * 后序查找
     * @param no
     * @return
     */
    public TreeNode postSearch(int no){
        if (this.root!=null){
            return this.root.postOrderSearch(no);
        }else {
            return null;
        }
    }

    /**
     * 删除结点
     * @param no
     */
    public void delNode(int no) {
        if(root != null) {
            //如果只有一个root结点, 这里立即判断root是不是就是要删除结点
            if(root.getNo() == no) {
                root = null;
            } else {
                //递归删除
                root.deleteNode(no);
            }
        }else{
            System.out.println("空树，不能删除~");
        }
    }
}


/**
 * 树节点
 */
class TreeNode{
    private int no;

    private String name;

    private TreeNode left;

    private TreeNode right;

    public TreeNode(int no, String name) {
        this.no = no;
        this.name = name;
    }

    public int getNo() {
        return no;
    }

    public void setNo(int no) {
        this.no = no;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public TreeNode getLeft() {
        return left;
    }

    public void setLeft(TreeNode left) {
        this.left = left;
    }

    public TreeNode getRight() {
        return right;
    }

    public void setRight(TreeNode right) {
        this.right = right;
    }

    @Override
    public String toString() {
        return "TreeNode{" +
                "no=" + no +
                ", name='" + name + '\'' +
                '}';
    }

    /**
     * 前序遍历
     */
    public void  preOrderTraversal(){
        System.out.println(this);
        if (this.left!=null){
            this.left.preOrderTraversal();
        }
        if(this.right !=null){
            this.right.preOrderTraversal();
        }
    }

    /**
     * 中序遍历
     */
    public void inOrderTraversal(){
        if(this.left!=null){
            this.left.inOrderTraversal();
        }
        System.out.println(this);
        if (this.right!=null){
            this.right.inOrderTraversal();
        }
    }


    /**
     * 后序遍历
     */
    public void postOrderTraversal(){
        if (this.left!=null){
            this.left.postOrderTraversal();
        }
        if (this.right!=null){
            this.right.postOrderTraversal();
        }
        System.out.println(this);
    }

    /**
     *前序查找
     * @param no  编号
     * @return
     */
    public TreeNode preOrderSearch(int no){
        if (this.no == no){
            return this;
        }
        //结果
        TreeNode resultNode = null;
        if (this.left!=null){
            resultNode = this.left.preOrderSearch(no);
        }
        if (resultNode !=null){
            return resultNode;
        }
        if(this.right !=null){
            resultNode = this.right.preOrderSearch(no);
        }
        return resultNode;
    }

    /**
     * 中序查找
     * @param no
     * @return
     */
    public TreeNode inOrderSearch(int no){
        //结果
        TreeNode resultNode = null;
        if (this.left != null){
            resultNode = this.left.inOrderSearch(no);
        }
        if (resultNode != null){
            return resultNode;
        }
        //如果找到则返回
        if (this.no == no){
            return this;
        }
        //否在继续右递归
        if (this.right!= null){
            resultNode = this.right.inOrderSearch(no);
        }
        return  resultNode;
    }

    /**
     *后序查找
     * @param no
     * @return
     */
    public TreeNode postOrderSearch(int no){
        TreeNode resultNode = null;
        if (this.left !=null){
            resultNode = this.left.postOrderSearch(no);
        }
        //左子树找到
        if (resultNode!=null){
            return resultNode;
        }
        //如果左子树没查找到，右递归
        if (this.right!=null){
            resultNode =this.right.postOrderSearch(no);
        }
        if (resultNode!=null){
            return resultNode;
        }
        if (this.no ==no){
            return this;
        }
        return resultNode;
    }

    /**
     * 递归删除节点
     * 如果是叶子节点直接删除，如果是树
     * @param no
     */
    public void deleteNode(int no){
        //思路
		/**
		 * 	1. 因为我们的二叉树是单向的，所以我们是判断当前结点的子结点是否需要删除结点，而不能去判断当前这个结点是不是需要删除结点.
			2. 如果当前结点的左子结点不为空，并且左子结点 就是要删除结点，就将this.left = null; 并且就返回(结束递归删除)
			3. 如果当前结点的右子结点不为空，并且右子结点 就是要删除结点，就将this.right= null ;并且就返回(结束递归删除)
			4. 如果第2和第3步没有删除结点，那么我们就需要向左子树进行递归删除
			5.  如果第4步也没有删除结点，则应当向右子树进行递归删除.
		 */
        //2. 如果当前结点的左子结点不为空，并且左子结点 就是要删除结点，就将this.left = null; 并且就返回(结束递归删除)
        if(this.left != null && this.left.no == no) {
            this.left = null;
            return;
        }
        //3.如果当前结点的右子结点不为空，并且右子结点 就是要删除结点，就将this.right= null ;并且就返回(结束递归删除)
        if(this.right != null && this.right.no == no) {
            this.right = null;
            return;
        }
        //4.我们就需要向左子树进行递归删除
        if(this.left != null) {
            this.left.deleteNode(no);
        }
        //5.则应当向右子树进行递归删除
        if(this.right != null) {
            this.right.deleteNode(no);
        }
    }


}
